package com.biostime.springdraw.common.wechat;

import java.io.IOException;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.core.io.Resource;

import com.biostime.springdraw.common.utils.SpringContextHolder;
import com.biostime.springdraw.common.utils.StringUtils;

import me.chanjar.weixin.common.bean.WxMenu;
import me.chanjar.weixin.common.exception.WxErrorException;
import me.chanjar.weixin.common.session.WxSessionManager;
import me.chanjar.weixin.mp.api.WxMpInMemoryConfigStorage;
import me.chanjar.weixin.mp.api.WxMpMessageHandler;
import me.chanjar.weixin.mp.api.WxMpMessageRouter;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.api.WxMpServiceImpl;
import me.chanjar.weixin.mp.bean.WxMpXmlMessage;
import me.chanjar.weixin.mp.bean.WxMpXmlOutMessage;
import me.chanjar.weixin.mp.bean.WxMpXmlOutTextMessage;

public class WxMpServlet extends HttpServlet {

	  /**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	
	protected WxMpInMemoryConfigStorage wxMpConfigStorage;
	  protected WxMpService wxMpService;
	  protected WxMpMessageRouter wxMpMessageRouter;

	  @Override public void init() throws ServletException {
	    super.init();

	    wxMpConfigStorage = new WxMpInMemoryConfigStorage();
	    wxMpConfigStorage.setAppId("wxb9cfab9710359e7a"); // 设置微信公众号的appid
	    wxMpConfigStorage.setSecret("94a90c18b4dd6b533e371c0ef84f711c"); // 设置微信公众号的app corpSecret
	    wxMpConfigStorage.setToken("haozi"); // 设置微信公众号的token
	    wxMpConfigStorage.setAesKey("FlI3ni3WcfrObA9169Rm6WIOPUiQe0We26coCZ6yeWw"); // 设置微信公众号的EncodingAESKey

	    wxMpService = new WxMpServiceImpl();
	    wxMpService.setWxMpConfigStorage(wxMpConfigStorage);

	    WxMpMessageHandler handler = new WxMpMessageHandler() {
			@Override
			public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map<String, Object> context, WxMpService wxMpService, WxSessionManager sessionManager) throws WxErrorException {
				boolean result = true;
				
				Resource resource = SpringContextHolder.getApplicationContext().getResource("classpath:menus/v1.json");
				try {
					WxMenu wxMenu = WxMenu.fromJson(resource.getInputStream());
					
					// 设置菜单
					wxMpService.menuCreate(wxMenu);	
				} catch (IOException e) {
					e.printStackTrace();
					
					result = false;
				}
				
				WxMpXmlOutTextMessage m = WxMpXmlOutMessage.TEXT()
							.content(result ? "菜单创建成功" : "菜单创建失败")
							.fromUser(wxMessage.getToUserName())
							.toUser(wxMessage.getFromUserName())
							.build();
		        return m;
			}
	    };

	    wxMpMessageRouter = new WxMpMessageRouter(wxMpService);
	    wxMpMessageRouter
	        .rule()
	        .async(false)
	        .content("menu_v1") // 拦截内容为“哈哈”的消息
	        .handler(handler)
	        .end();

	  }

	  @Override 
	  protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
	
		    response.setContentType("text/html;charset=utf-8");
		    response.setStatus(HttpServletResponse.SC_OK);

		    String signature = request.getParameter("signature");
		    String nonce = request.getParameter("nonce");
		    String timestamp = request.getParameter("timestamp");

		    if (!wxMpService.checkSignature(timestamp, nonce, signature)) {
		    	// 消息签名不正确，说明不是公众平台发过来的消息
		    	response.getWriter().println("非法请求");
		    	return;
		    }

		    String echostr = request.getParameter("echostr");
		    if (StringUtils.isNotBlank(echostr)) {
		    	// 说明是一个仅仅用来验证的请求，回显echostr
		    	response.getWriter().println(echostr);
		    	return;
		    }

		    String encryptType = StringUtils.isBlank(request.getParameter("encrypt_type")) ?
	        "raw" :
	        request.getParameter("encrypt_type");

		    if ("raw".equals(encryptType)) {
		    	// 明文传输的消息
		    	WxMpXmlMessage inMessage = WxMpXmlMessage.fromXml(request.getInputStream());
		    	WxMpXmlOutMessage outMessage = wxMpMessageRouter.route(inMessage);
		    	response.getWriter().write(outMessage.toXml());
		    	return;
		    }

		    if ("aes".equals(encryptType)) {
		    	// 是aes加密的消息
		    	String msgSignature = request.getParameter("msg_signature");
		    	WxMpXmlMessage inMessage = WxMpXmlMessage.fromEncryptedXml(request.getInputStream(), wxMpConfigStorage, timestamp, nonce, msgSignature);
		    	WxMpXmlOutMessage outMessage = wxMpMessageRouter.route(inMessage);
		    	response.getWriter().write(outMessage.toEncryptedXml(wxMpConfigStorage));
		    	return;
		    }

		    response.getWriter().println("不可识别的加密类型");
		    return;
	  }
	}
